iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
Mobile Development

在 iOS 專案上加上 Unit testing - 因為 You need testing系列 第 23

D23 - 在 iOS 專案加上測試-You need testing {handling JSON decode error}

  • 分享至 

  • xImage
  •  

上一篇講 Error handling 是指 Error 在 URLSession 時發生,可能是 4 開頭或 5 開頭的 Error。但有另一種可能,後端 HTTPURLResponse 的 status code 是回 2 開頭成功,但 json response 的格式和程式不一樣,問題可能在前端可能在後端,也可能是規格變更後,有一端沒有 sync 到。這會讓 JSON decode 解不開,今天的程式,是測 DecodingError

step1: 在 APIClientTest 中加上 Decode 的這一段

func testStockClosePriceListDecodeError() async throws {
        
        let url = try XCTUnwrap(URL(string: "foo"))
        let urlSessionMock = URLSessionProtocolMock()
        urlSessionMock.dataForDelegateReturnValue = (
            try JSONEncoder().encode("dummyObject"),
            HTTPURLResponse(url: url, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: nil)!
        )
        sut.session = urlSessionMock
        
        do {
            _ = try await sut.getStockClosPriceList()
            XCTFail("this test should not get here")
        } catch {
            XCTAssertTrue(error is Swift.DecodingError)
        }
    }

跑完測試後因為都 pass,如果想確認這一道測試,可以暫時把 APIClient 改成下面這樣,確認測試會 failed 後,再改回來

/// APIClient.swift
/// 確認 test 可以 failed 時的改法
func getStockClosPriceList() async throws -> [StockDailyInfoElement] {
        
        guard let url = URL(string: "https://openapi.twse.com.tw/v1/exchangeReport/STOCK_DAY_AVG_ALL") else {
            return []
        }
        
        let request = URLRequest(url: url)
        let (data, _) = try await session.data(for: request, delegate: nil)
        
        let stocks = try? JSONDecoder().decode([StockDailyInfoElement].self, from: data)

        return stocks ?? []
    } 
/// APIClient.swift
/// 確認後將 APIClient 改回來
func getStockClosPriceList() async throws -> [StockDailyInfoElement] {
        
        guard let url = URL(string: "https://openapi.twse.com.tw/v1/exchangeReport/STOCK_DAY_AVG_ALL") else {
            return []
        }
        
        let request = URLRequest(url: url)
        let (data, _) = try await session.data(for: request, delegate: nil)
        
        let stocks = try JSONDecoder().decode([StockDailyInfoElement].self, from: data)

        return stocks
    }


上一篇
D22 - 在 iOS 專案加上測試-You need testing {handling errors}
下一篇
D24 - 在 iOS 專案加上測試-You need testing {在 Test 啟動階段,換上測試用的 AppDelegate 適用於 UIKit 專案}
系列文
在 iOS 專案上加上 Unit testing - 因為 You need testing32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言